#pragma once

#include "HiredisAsyncContext.h"

#include <functional>
#include <string>
#include <thread>
#include <vector>

class HiredisSubscriber
{
    typedef std::function<void(const std::string &, const std::string &)> SubscribeCallback;

public:
    HiredisSubscriber();
    ~HiredisSubscriber();

protected:
    /**
     * @brief 订阅消息回调函数
     *
     * @param ctx
     * @param reply
     * @param privdata
     */
    static void onMessage(struct redisAsyncContext *ctx, void *reply, void *privdata);

    /**
     * @brief 任务处理线程
     *
     */
    void taskProcess();

public:
    /**
     * @brief 初始化
     *
     * @param ip
     * @param port
     * @return true
     * @return false
     */
    bool init(const std::string &ip, uint16_t port);

    /**
     * @brief 运行 Redis 订阅任务
     *
     * @param channels
     * @param cb
     * @return true
     * @return false
     */
    bool run(const std::vector<std::string> &&channels, SubscribeCallback cb);

    /**
     * @brief 停止任务
     *
     */
    void stop();

private:
    HiredisAsyncContext     *m_redis_ctx;
    SubscribeCallback        m_callback;
    bool                     m_runflag;
    std::thread              m_thread;
    std::vector<std::string> m_channels;
};